//
//  MJRefreshBackFooter.swift
//  OC-Swift
//
//  Created by 陆文宇 on 2017/2/15.
//  Copyright © 2017年 陆文宇. All rights reserved.
//

import UIKit

class MJRefreshBackFooter: MJRefreshFooter {
    
    var ignoredScrollViewContentInsetBottom: CGFloat = 0
    var lastRefreshCount: Int = 0
    var lastBottomDelta: CGFloat = 0
    var heightForContentBreakView: CGFloat {
        let h: CGFloat = scrollView!.frame.size.height - scrollViewOriginalInset!.bottom - scrollViewOriginalInset!.top
        return scrollView!.contentSize.height - h
    }
    var happenOffsetY: CGFloat {
        let deltaH: CGFloat = self.heightForContentBreakView
        if deltaH > 0 {
            return deltaH - scrollViewOriginalInset!.top
        } else {
            return -scrollViewOriginalInset!.top;
        }
    }
    override var state: MJRefreshComponent.MJRefreshState {
        set {
            let oldState: MJRefreshState = super.state
            if super.state != newValue {
                super.state = newValue
            }
            
            if state == .noMoreData || state == .idle {
                if .refreshing == oldState {
                    UIView.animate(withDuration: MJRefreshSlowAnimationDuration, animations: { 
                        self.scrollView!.mj_insetB -= self.lastBottomDelta
                        
                        if self.automaticallyChangeAlpha {
                            self.alpha = 0
                        }
                    }, completion: { (_) in
                        self.pullingPercent = 0
                        
                        if self.endRefreshingCompletionClosure != nil {
                            self.endRefreshingCompletionClosure!()
                        }
                    })
                }
                
                let deltaH: CGFloat = heightForContentBreakView
                if oldState == .refreshing && deltaH > 0 && scrollView!.mj_totalDataCount != lastRefreshCount {
                    scrollView!.mj_offsetY = scrollView!.mj_offsetY
                }
            } else if state == .refreshing {
                lastRefreshCount = scrollView!.mj_totalDataCount
                
                UIView.animate(withDuration: MJRefreshFastAnimationDuration, animations: { 
                    var bottom: CGFloat = self.mj_h + self.scrollViewOriginalInset!.bottom
                    let deltaH: CGFloat = self.heightForContentBreakView
                    if deltaH < 0 {
                        bottom -= deltaH
                    }
                    self.lastBottomDelta = bottom - self.scrollView!.mj_insetB
                    self.scrollView?.mj_insetB = bottom
                    self.scrollView?.mj_offsetY = self.happenOffsetY + self.mj_h
                }, completion: { (_) in
                    self.executeRefreshingCallback()
                })
            }
        }
        
        get {
            return _state
        }
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        
        scrollViewContentSizeDidChange(change: nil)
    }
    
    override func scrollViewContentOffsetDidChange(change: Dictionary<NSKeyValueChangeKey, Any>) {
        super.scrollViewContentOffsetDidChange(change: change)
        
        if state == .refreshing {
            return
        }
        
        scrollViewOriginalInset = scrollView!.contentInset
        let currentOffsetY: CGFloat = scrollView!.mj_offsetY
        let happenOffsetY: CGFloat = self.happenOffsetY
        if currentOffsetY <= happenOffsetY {
            return
        }
        
        let pullingPercent: CGFloat = (currentOffsetY - happenOffsetY) / mj_h
        
        if state == .noMoreData {
            self.pullingPercent = pullingPercent
            return
        }
        
        if scrollView!.isDragging {
            self.pullingPercent = pullingPercent
            let normal2pullingOffsetY: CGFloat = happenOffsetY + mj_h
            
            if state == .idle && currentOffsetY > normal2pullingOffsetY {
                state = .pulling
            } else if state == .pulling && currentOffsetY <= normal2pullingOffsetY {
                state = .idle
            }
        } else if state == .pulling {
            beginRefreshing()
        } else if pullingPercent < 1 {
            self.pullingPercent = pullingPercent
        }
    }
    
    override func scrollViewContentSizeDidChange(change: Dictionary<NSKeyValueChangeKey, Any>?) {
        super.scrollViewContentSizeDidChange(change: change)
        
        let contentHeight: CGFloat = (scrollView?.mj_contentH ?? 0) + ignoredScrollViewContentInsetBottom
        let scrollHeight: CGFloat = (scrollView?.mj_h ?? 0) - scrollViewOriginalInset!.top - scrollViewOriginalInset!.bottom + ignoredScrollViewContentInsetBottom
        mj_y = max(contentHeight, scrollHeight)
    }
    
    override func endRefreshing() {
        DispatchQueue.main.async {
            self.state = .idle
        }
    }
 
    override func endRefreshingWithNoMoreData() {
        DispatchQueue.main.async {
            self.state = .noMoreData
        }
    }


    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

}
